package burubaka.service;

import java.util.HashMap;
import java.util.List;
import java.util.logging.Logger;

import org.slim3.datastore.Datastore;

import burubaka.BurubakaConstants;
import burubaka.meta.TotalResultMeta;
import burubaka.model.TotalResult;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Transaction;

public class TotalResultService {

	private static final Logger log = Logger.getLogger(TotalResultService.class.getName());

	private TotalResultMeta meta = new TotalResultMeta();

	/**
	 * キー検索
	 * 
	 * @param key
	 * @return TotalResult
	 */
	public TotalResult findByKey(Key key) {
		return Datastore.query(TotalResult.class, key).asSingle();
	}

	/**
	 * 予想屋の本年度成績取得
	 * 
	 * @param key
	 * @return TotalResult
	 */
	public TotalResult getThisYearResult(Key key) {
		return Datastore.query(TotalResult.class, key).filter(meta.year.equal(BurubakaConstants.CURRENT_YEAR))
				.asSingle();
	}

	/**
	 * ランキング取得
	 * 
	 * @param year
	 * @return RaceInfoList
	 */
	public List<TotalResult> getRanking(String year) {
		return Datastore.query(meta).filter(meta.year.equal(year)).asList();
	}

	/**
	 * 回収ランキング取得
	 * 
	 * @param year
	 * @return TotalResult
	 */
	public List<TotalResult> getRankingForWithdrawal(String year) {
		return Datastore.query(meta).filter(meta.year.equal(year)).sort(this.meta.withdrawal.desc, this.meta.bets.desc)
				.asList();
	}

	/**
	 * 回収ランキング取得
	 * 
	 * @param year
	 * @param limit
	 * @return TotalResult
	 */
	public List<TotalResult> getRankingForWithdrawal(String year, int limit) {
		return Datastore.query(meta).filter(meta.year.equal(year)).sort(this.meta.withdrawal.desc, this.meta.bets.desc)
				.limit(limit).asList();
	}

	/**
	 * 回収ランキングマップ取得
	 * 
	 * @return HashMap
	 */
	public HashMap<Key, String> getRankingMapForWithdrawal() {
		HashMap<Key, String> ret = new HashMap<Key, String>();
		List<TotalResult> list = getRankingForWithdrawal(BurubakaConstants.CURRENT_YEAR);

		long old = 0;
		String oldOrder = "";
		int i = 1;
		for (TotalResult totalResult : list) {
			String order = String.valueOf(i);
			if (totalResult.getWithdrawal() == old) {
				order = oldOrder;
			}
			if (totalResult.getBets() == 0) {
				order = "";
			}
			ret.put(totalResult.getKey(), order);

			old = totalResult.getWithdrawal();
			oldOrder = order;
			i++;
		}
		return ret;
	}

	/**
	 * 回収率ランキング取得
	 * 
	 * @param year
	 * @return TotalResult
	 */
	public List<TotalResult> getRankingForWithdrawalRate(String year) {
		return Datastore.query(meta).filter(meta.year.equal(year))
				.sort(this.meta.withdrawalRate.desc, this.meta.bets.desc).asList();
	}

	/**
	 * 回収率ランキング取得
	 * 
	 * @param year
	 * @return TotalResult
	 */
	public List<TotalResult> getRankingForWithdrawalRate(String year, int limit) {
		return Datastore.query(meta).filter(meta.year.equal(year))
				.sort(this.meta.withdrawalRate.desc, this.meta.bets.desc).limit(limit).asList();
	}

	/**
	 * 回収率ランキングマップ取得
	 * 
	 * @return HashMap
	 */
	public HashMap<Key, String> getRankingMapForWithdrawalRate() {
		HashMap<Key, String> ret = new HashMap<Key, String>();
		List<TotalResult> list = getRankingForWithdrawalRate(BurubakaConstants.CURRENT_YEAR);

		double old = 0;
		String oldOrder = "";
		int i = 1;
		for (TotalResult totalResult : list) {
			String order = String.valueOf(i);
			if (totalResult.getWithdrawalRate() == old) {
				order = oldOrder;
			}
			if (totalResult.getBets() == 0) {
				order = "";
			}
			ret.put(totalResult.getKey(), order);

			old = totalResult.getWithdrawalRate();
			oldOrder = order;
			i++;
		}
		return ret;
	}

	/**
	 * 的中ランキング取得
	 * 
	 * @param year
	 * @return TotalResult
	 */
	public List<TotalResult> getRankingForHit(String year) {
		return Datastore.query(meta).filter(meta.year.equal(year)).sort(this.meta.hit.desc, this.meta.bets.desc)
				.asList();
	}

	/**
	 * 的中ランキング取得
	 * 
	 * @param year
	 * @param limit
	 * @return TotalResult
	 */
	public List<TotalResult> getRankingForHit(String year, int limit) {
		return Datastore.query(meta).filter(meta.year.equal(year)).sort(this.meta.hit.desc, this.meta.bets.desc)
				.limit(limit).asList();
	}

	/**
	 * 的中ランキングマップ取得
	 * 
	 * @return HashMap
	 */
	public HashMap<Key, String> getRankingMapForHit() {
		HashMap<Key, String> ret = new HashMap<Key, String>();
		List<TotalResult> list = getRankingForHit(BurubakaConstants.CURRENT_YEAR);

		int old = 0;
		String oldOrder = "";
		int i = 1;
		for (TotalResult totalResult : list) {
			String order = String.valueOf(i);
			if (totalResult.getHit() == old) {
				order = oldOrder;
			}
			if (totalResult.getBets() == 0) {
				order = "";
			}
			ret.put(totalResult.getKey(), order);

			old = totalResult.getHit();
			oldOrder = order;
			i++;
		}
		return ret;
	}

	/**
	 * 的中率ランキング取得
	 * 
	 * @param year
	 * @return TotalResult
	 */
	public List<TotalResult> getRankingForHitRate(String year) {
		return Datastore.query(meta).filter(meta.year.equal(year)).sort(this.meta.hitRate.desc, this.meta.bets.desc)
				.asList();
	}

	/**
	 * 的中率ランキング取得
	 * 
	 * @param year
	 * @param limit
	 * @return TotalResult
	 */
	public List<TotalResult> getRankingForHitRate(String year, int limit) {
		return Datastore.query(meta).filter(meta.year.equal(year)).sort(this.meta.hitRate.desc, this.meta.bets.desc)
				.limit(limit).asList();
	}

	/**
	 * 的中率ランキングマップ取得
	 * 
	 * @return HashMap
	 */
	public HashMap<Key, String> getRankingMapForHitRate() {
		HashMap<Key, String> ret = new HashMap<Key, String>();
		List<TotalResult> list = getRankingForHitRate(BurubakaConstants.CURRENT_YEAR);

		double old = 0;
		String oldOrder = "";
		int i = 1;
		for (TotalResult totalResult : list) {
			String order = String.valueOf(i);
			if (totalResult.getHitRate() == old) {
				order = oldOrder;
			}
			if (totalResult.getBets() == 0) {
				order = "";
			}
			ret.put(totalResult.getKey(), order);

			old = totalResult.getHitRate();
			oldOrder = order;
			i++;
		}
		return ret;
	}

	/**
	 * 登録
	 * 
	 * @param model
	 * @return TotalResult
	 */
	public TotalResult regist(TotalResult model) {
		Transaction tx = Datastore.beginTransaction();
		Datastore.put(model);
		tx.commit();
		return model;
	}

	/**
	 * 登録
	 * 
	 * @param model
	 * @return TotalResult
	 */
	public List<TotalResult> regist(List<TotalResult> list) {
		Transaction tx = Datastore.beginTransaction();
		Datastore.put(list);
		tx.commit();
		return list;
	}

	/**
	 * 登録
	 * 
	 * @param RankingBean
	 * @param ancKey
	 * @return boolean
	 */
	public boolean regist(TotalResult model, Key ancKey) {

		Transaction tx = Datastore.beginTransaction();
		Key childKey = Datastore.allocateId(ancKey, TotalResult.class);
		if (childKey != null) {
			model.setKey(childKey);
		}
		Datastore.put(model);
		tx.commit();

		return true;
	}

	/**
	 * 削除
	 * 
	 * @param model
	 * @return boolean
	 */
	public boolean delete(TotalResult model) {
		Transaction tx = Datastore.beginTransaction();
		Datastore.delete(model.getKey());
		tx.commit();
		return true;
	}
}
